<?php
/**
 * Here is your custom functions.
 */

use think\facade\Cache;
use think\facade\Db;
use Casbin\WebmanPermission\Permission;
use support\lib\IpToAddress;
use support\lib\Env;
use think\helper\Str;
use Webman\Push\Api;

/**
 * webman-push推送
 */
if ( ! function_exists('push_webman')) {
    function push_webman($channels, $event = 'message', $message = [])
    {
        $api = new Api('http://127.0.0.1:3232', config('plugin.webman.push.app.app_key'),
            config('plugin.webman.push.app.app_secret'));
        $api->trigger($channels, $event, $message);
    }

}
/**
 * 生成表单token令牌
 */
if ( ! function_exists('token')) {
    function token($type = 'md5')
    {
        $name  = '__huicmf_token__';
        $token = request()->buildToken($name, $type);

        return '<input type="" name="'.$name.'" value="'.$token.'" />';
    }
}

/**
 * 获取当前的 response 输出类型
 * @access protected
 * @return string
 */
function getResponseType()
{
    return (request()->method()) ? 'json' : 'html';
}

/**
 * 返回success_json数组
 *
 * @param $arr
 *
 * @return string
 */
function success_json($msg = 'ok', $data = [], $count = 0, $url = '', $wait = 3)
{
    /*if (empty($count)) {
        return json(['code' => 200, 'code_lay' => 0, 'msg' => $msg, 'data' => $data]);
    } else {
        return json(['code' => 200, 'code_lay' => 0, 'msg' => $msg, 'count' => $count, 'data' => $data]);
    }*/
    $result = ['code' => 200, 'code_lay' => 0, 'msg' => $msg, 'count' => $count, 'data' => $data];

    if (getResponseType() == 'html' || $url != '') {
        $huicmfConfig   = config('huicmf');
        $result['url']  = $url;
        $result['wait'] = $wait;
        $response       = view($huicmfConfig['dispatch_success_tmpl'], $result);

        return $response;
    } else {
        return json($result);
    }
}

/**
 * 返回success_json数组
 *
 * @param mixed $msg  提示信息,若要指定错误码,可以传数组,格式为['code'=>您的错误码,'msg'=>'您的错误消息']
 * @param mixed $data 返回的数据
 * @param array $url  跳转url地址
 *
 * @return string
 */
function error_json($msg = '', $data = [], $url = '', $wait = 3)
{
    $code = 0;
    if (is_array($msg)) {
        $code = $msg['code'];
        $msg  = $msg['msg'];
    }
    $result = [
        'code' => $code,
        'msg'  => $msg,
        'data' => $data,
    ];

    if (getResponseType() == 'html' || $url != '') {
        $huicmfConfig   = config('huicmf');
        $result['url']  = $url;
        $result['wait'] = $wait;
        $response       = view($huicmfConfig['dispatch_error_tmpl'], $result);

        return $response;
    } else {
        return json($result);
    }

}

if ( ! function_exists('cmf_get_admin_id')) {
    function cmf_get_admin_id()
    {
        $adminId = session()->get('session_admin_id');

        return $adminId ? $adminId : '';
    }
}

if ( ! function_exists('cmf_get_role_id')) {
    function cmf_get_role_id()
    {
        $adminInfo = cmf_get_admin_info();
        $roleId    = $adminInfo['role_id'];

        return $roleId ? $roleId : '';
    }
}
if ( ! function_exists('cmf_get_admin_info')) {
    function cmf_get_admin_info($value_name = '')
    {
        $adminId = cmf_get_admin_id();
        if (empty($value_name)) {
            $adminInfo = Db::name('admin')->where('id', $adminId)->find();
        } else {
            $adminInfo = Db::name('admin')->where('id', $adminId)->value($value_name);
        }

        return $adminInfo;
    }
}

/**
 * CMF密码加密方法
 *
 * @param string $pw       要加密的原始密码
 * @param string $authCode 加密字符串,salt
 *
 * @return string
 */
if ( ! function_exists('cmf_password')) {
    function cmf_password($pw, $authCode = 'hui_cmf6_webman')
    {
        $result = md5('####'.md5($pw).$authCode);

        return $result;
    }
}

/**
 * 打印各种类型的数据，调试程序时使用。
 *
 * @param mixed $var 变量
 *
 * @return void or string
 */
if ( ! function_exists('dump')) {
    function dump($var)
    {
        ob_start();
        var_dump($var);
        $output = ob_get_clean();
        if ( ! extension_loaded('xdebug')) {
            $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output);
        }

        echo $output;

        return null;
    }
}

/**
 * 获取客户端IP地址
 *
 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
 * @param boolean $adv  是否进行高级模式获取（有可能被伪装）
 *
 * @return string
 */
if ( ! function_exists('get_client_ip')) {
    function get_client_ip($type = 0, $adv = true)
    {
        return request()->getRealIp($safe_mode = true);
    }
}

/**
 * 根据IP地址判断地区
 *
 * @param $clientIP
 *
 * @return string
 */
function getIpToArea($clientIP)
{
    $ipToAddress = new IpToAddress();
    $res         = $ipToAddress->ipToAddress($clientIP);

    return $res;
}

/**
 * 获取系统配置信息
 *
 * @param $key 键值，可为空，为空获取整个数组
 *
 * @return array|string
 */
if ( ! function_exists('get_config')) {
    function get_config($key = '')
    {
        $configs = [];
        if (Cache::get('cacheSystemConfig')) {
            $data = Cache::get('cacheSystemConfig');
        } else {
            $data = Db::name('config')->where('status', 1)->select()->toArray();
            Cache::set('cacheSystemConfig', $data);
        }
        foreach ($data as $val) {
            $configs[$val['name']] = $val['value'];
        }
        if ( ! $key) {
            return $configs;
        } else {
            return array_key_exists($key, $configs) ? $configs[$key] : '';
        }
    }
}

if ( ! function_exists('curl_get')) {
    function curl_get($url)
    {
        $ch       = curl_init();
        $header[] = "";
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_REFERER, $url);
        curl_setopt($ch, CURLOPT_USERAGENT,
            "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $content = curl_exec($ch);
        curl_close($ch);

        return $content;
    }
}

/**
 * @param $post_url
 * @param $post_data
 *
 * @return bool|mixed|string
 */
if ( ! function_exists('curl_post')) {
    function curl_post($post_url, $post_data, $header = [])
    {
        if (is_array($post_data)) {
            $post_data = http_build_query($post_data);
        }
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_URL, $post_url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
        curl_setopt($ch, CURLOPT_USERAGENT, '');
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $output = curl_exec($ch);
        curl_close($ch);

        return $output;
    }
}

/**
 * 按钮权限验证
 */
if ( ! function_exists('check_auth')) {
    function check_auth($rule_name = '')
    {
        $adminId     = cmf_get_admin_id();
        $adminRoleId = cmf_get_role_id();
        if ($adminRoleId === 1) {
            return true;
        }
        dump($adminId);
        dump($rule_name);
        $res = Permission::enforce("admin_role_".$adminId, strtolower($rule_name), 'GET');

        return $res;
    }
}

/**
 * 记录日志
 *
 * @param $err_arr 日志信息
 * @param $path    日志路径
 *
 * @return bool
 */
if ( ! function_exists('write_error_log')) {
    function write_error_log($err_arr, $path = '', $file_fix = 'log_')
    {
        if (is_array($err_arr)) {
            $message2 = json_encode($err_arr).PHP_EOL;
        } else {
            $message2 = $err_arr.PHP_EOL;
        }
        $dateTime = date('Y-m-d H:i:s');

        $w_msg = '';
        $w_msg .= "【".$dateTime."】".PHP_EOL;
        $w_msg .= $message2;
        $w_msg .= '============================'.PHP_EOL.PHP_EOL;

        $dirPath = dirname(dirname(__FILE__).DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
        $path    = $dirPath.DIRECTORY_SEPARATOR."log".DIRECTORY_SEPARATOR.$path;
        if ( ! is_dir($path)) {
            @mkdir($path, 0777, true);
        }
        $dateTime2 = date('Ymd');
        $file      = $path.DIRECTORY_SEPARATOR.$file_fix.$dateTime2.'.txt';
        error_log($w_msg, 3, $file);
    }
}

/*
 * __url
 */
if ( ! function_exists('__url')) {
    function __url($path, $vars = [])
    {
        // 解析参数
        if (is_string($vars)) {
            parse_str($vars, $vars);
        }
        $fixStr = '';
        if ( ! empty($vars)) {
            $fixStr = "?".http_build_query($vars);
        }

        $newPath = "/".request()->app."/".$path.$fixStr;

        return $newPath;
    }
}

/**
 * 转换字节数为其他单位
 *
 * @param string $filesize 字节大小
 *
 * @return    string    返回大小
 */
if ( ! function_exists('sizeCount')) {
    function sizeCount($filesize)
    {
        if ($filesize >= 1073741824) {
            $filesize = round($filesize / 1073741824 * 100) / 100 .' GB';
        } elseif ($filesize >= 1048576) {
            $filesize = round($filesize / 1048576 * 100) / 100 .' MB';
        } elseif ($filesize >= 1024) {
            $filesize = round($filesize / 1024 * 100) / 100 .' KB';
        } else {
            $filesize = $filesize.' Bytes';
        }

        return $filesize;
    }
}

/**
 * 　　* 下划线转驼峰
 * 　　* 思路:
 * 　　* step1.原字符串转小写,原字符串中的分隔符用空格替换,在字符串开头加上分隔符
 * 　　* step2.将字符串中每个单词的首字母转换为大写,再去空格,去字符串首部附加的分隔符.
 * 　　*/
function camelize($uncamelized_words, $separator = '_')
{
    $uncamelized_words = $separator.str_replace($separator, " ", strtolower($uncamelized_words));

    return ltrim(str_replace(" ", "", ucwords($uncamelized_words)), $separator);
}

/**
 * 　　* 驼峰命名转下划线命名
 * 　　* 思路:
 * 　　* 小写和大写紧挨一起的地方,加上分隔符,然后全部转小写
 * 　　*/
function uncamelize($camelCaps, $separator = '_')
{
    return strtolower(preg_replace('/([a-z])([A-Z])/', "$1".$separator."$2", $camelCaps));
}

/**
 * 二位数组重新组合数据
 *
 * @param $array
 * @param $key
 *
 * @return array
 */
if ( ! function_exists('array_format_key')) {
    function array_format_key($array, $key)
    {
        $newArray = [];
        foreach ($array as $vo) {
            $newArray[$vo[$key]] = $vo;
        }

        return $newArray;
    }

}
/**
 * 字符截取
 *
 * @param $string    要截取的字符串
 * @param $length    截取长度
 * @param $dot       截取之后用什么表示
 * @param $code      编码格式，支持UTF8/GBK
 */
if ( ! function_exists('str_cut')) {
    function str_cut($string, $length, $dot = '...', $code = 'utf-8')
    {
        $strlen = strlen($string);
        if ($strlen <= $length) {
            return $string;
        }
        $string = str_replace(array(
            ' ',
            '&nbsp;',
            '&amp;',
            '&quot;',
            '&#039;',
            '&ldquo;',
            '&rdquo;',
            '&mdash;',
            '&lt;',
            '&gt;',
            '&middot;',
            '&hellip;',
            '\r\n'
        ), array('∵', ' ', '&', '"', "'", '“', '”', '—', '<', '>', '·', '…'), $string);
        $strcut = '';
        if ($code == 'utf-8') {
            $length = intval($length - strlen($dot) - $length / 3);
            $n      = $tn = $noc = 0;
            while ($n < strlen($string)) {
                $t = ord($string[$n]);
                if ($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
                    $tn = 1;
                    $n++;
                    $noc++;
                } elseif (194 <= $t && $t <= 223) {
                    $tn  = 2;
                    $n   += 2;
                    $noc += 2;
                } elseif (224 <= $t && $t <= 239) {
                    $tn  = 3;
                    $n   += 3;
                    $noc += 2;
                } elseif (240 <= $t && $t <= 247) {
                    $tn  = 4;
                    $n   += 4;
                    $noc += 2;
                } elseif (248 <= $t && $t <= 251) {
                    $tn  = 5;
                    $n   += 5;
                    $noc += 2;
                } elseif ($t == 252 || $t == 253) {
                    $tn  = 6;
                    $n   += 6;
                    $noc += 2;
                } else {
                    $n++;
                }
                if ($noc >= $length) {
                    break;
                }
            }
            if ($noc > $length) {
                $n -= $tn;
            }
            $strcut = substr($string, 0, $n);
            $strcut = str_replace(array('∵', '&', '"', "'", '“', '”', '—', '<', '>', '·', '…'), array(
                ' ',
                '&amp;',
                '&quot;',
                '&#039;',
                '&ldquo;',
                '&rdquo;',
                '&mdash;',
                '&lt;',
                '&gt;',
                '&middot;',
                '&hellip;'
            ), $strcut);
        } else {
            $dotlen      = strlen($dot);
            $maxi        = $length - $dotlen - 1;
            $current_str = '';
            $search_arr  = array('&', ' ', '"', "'", '“', '”', '—', '<', '>', '·', '…', '∵');
            $replace_arr = array(
                '&amp;',
                '&nbsp;',
                '&quot;',
                '&#039;',
                '&ldquo;',
                '&rdquo;',
                '&mdash;',
                '&lt;',
                '&gt;',
                '&middot;',
                '&hellip;',
                ' '
            );
            $search_flip = array_flip($search_arr);
            for ($i = 0; $i < $maxi; $i++) {
                $current_str = ord($string[$i]) > 127 ? $string[$i].$string[++$i] : $string[$i];
                if (in_array($current_str, $search_arr)) {
                    $key         = $search_flip[$current_str];
                    $current_str = str_replace($search_arr[$key], $replace_arr[$key], $current_str);
                }
                $strcut .= $current_str;
            }
        }

        return $strcut.$dot;
    }
}

//数组排序
if ( ! function_exists('arrayOrder')) {
    function arrayOrder($array, $vkey)
    {
        $newArr = array();
        foreach ($array as $key => $v) {
            $newArr[$key][$vkey] = $v[$vkey];
        }
        array_multisort($newArr, SORT_DESC, $array);//SORT_DESC为降序，SORT_ASC为升序

        return $array;
    }
}

/**
 * 列出目录下所有文件
 *
 * @param string $path 路径
 * @param string $exts 扩展名
 * @param array  $list 增加的文件列表
 *
 * @return  array  所有满足条件的文件
 */
function dir_path($path)
{
    $path = str_replace('\\', '/', $path);
    if (substr($path, -1) != '/') {
        $path = $path.'/';
    }

    return $path;
}

/**
 * 列出目录下的所有文件
 *
 * @param str   $path 目录
 * @param str   $exts 后缀
 * @param array $list 路径数组
 *
 * @return array 返回路径数组
 */
function dir_list($path, $exts = '', $list = array())
{
    $path  = dir_path($path);
    $files = glob($path.'*');
    foreach ($files as $v) {
        if ( ! $exts || preg_match("/\.($exts)/i", $v)) {
            $list[] = $v;
            if (is_dir($v)) {
                $list = dir_list($v, $exts, $list);
            }
        }
    }

    return $list;
}

/**
 * 加密字符串
 *
 * @param [type] $str 待加密的字符串
 *
 * @return void
 */
if ( ! function_exists('half_replace')) {
    function half_replace($str)
    {
        $len = strlen($str) / 2;

        return substr_replace($str, str_repeat('*', $len), ceil(($len) / 2), $len);
    }
}

/**
 * url参数转换为数组
 *
 * @param $query
 *
 * @return array
 */
if ( ! function_exists('convertUrlQuery')) {
    function convertUrlQuery($query)
    {
        $queryParts = explode('&', $query);
        $params     = array();
        foreach ($queryParts as $param) {
            $item             = explode('=', $param);
            $params[$item[0]] = $item[1];
        }

        return $params;
    }
}
/**
 * 删除目录及目录下面的所有文件
 *
 * @param string $dir 路径
 *
 * @return  bool   如果成功则返回 TRUE，失败则返回 FALSE
 */
if ( ! function_exists('dir_delete')) {
    function dir_delete($dir)
    {
        $dir = dir_path($dir);
        if ( ! is_dir($dir)) {
            return false;
        }
        $list = glob($dir.'*');
        foreach ($list as $v) {
            is_dir($v) ? dir_delete($v) : @unlink($v);
        }

        return @rmdir($dir);
    }
}

/**
 * 重载系统
 * return bool
 */
if ( ! function_exists('system_reload')) {
    function system_reload(): bool
    {
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
            return false;
        }
        if (function_exists('posix_kill') && function_exists('posix_getppid')) {
            posix_kill(posix_getppid(), 10);

            return true;
        }

        return false;
    }
}

if ( ! function_exists('get_env')) {
    function get_env($name, $default = '')
    {
        return Env::get($name, $default);
    }
}
if ( ! function_exists('set_env')) {
    function set_env($name, $value)
    {
        return Env::set($name, $value);
    }
}

/**
 * 获取插件目录
 *
 * @param string $string
 *
 * @return string
 */
if ( ! function_exists('plugin_path')) {
    function plugin_path($string = '')
    {
        $pluginPath = base_path().DIRECTORY_SEPARATOR.'plugin'.DIRECTORY_SEPARATOR;

        return $string ? $pluginPath.$string.DIRECTORY_SEPARATOR : $pluginPath.DIRECTORY_SEPARATOR;
    }
}

/**
 * 获取插件配置
 *
 * @param string $name  插件名
 * @param bool   $force 是否缓存
 *
 * @return array
 */
if ( ! function_exists('get_plugin_config')) {
    function get_plugin_config($name, $force = false)
    {
        $array = [];

        $pluginPath = plugin_path($name);
        $filePath   = $pluginPath.'config.json';
        if (is_file($filePath)) {
            $array = json_decode(@file_get_contents($filePath), true);
            if (is_array($array)) {
                $array['path']   = $pluginPath;
                $array['config'] = is_file($pluginPath.'config.html') ? 1 : 0;
            }
        }

        return $array ?: [];
    }
}

/**
 * 设置插件配置
 *
 * @param string $name 插件名
 * @param array  $value
 *
 * @return array
 */
if ( ! function_exists('set_plugin_config')) {
    function set_plugin_config($name, $value)
    {
        $config   = get_plugin_config($name, true);
        $config   = array_merge($config, $value);
        $filePath = plugin_path($name).'/config.json';
        write_file($filePath, json_encode($config, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
        plugin_refresh_hooks();

        return $config;
    }
}

/**
 * 查询插件信息
 * @return string
 */
if ( ! function_exists('get_plugin_query')) {
    function get_plugin_query()
    {
        //return get_api_url().'plugin/query';
    }
}

/**
 * 获取插件类的类名
 *
 * @param string $name  插件名
 * @param string $class 当前类名
 *
 * @return string
 */
if ( ! function_exists('get_plugin_class')) {
    function get_plugin_class($name, $class = '')
    {
        $name      = trim($name);
        $class     = Str::studly(! $class ? $name : $class);
        $namespace = "\\plugin\\".$name."\\".$class;

        return class_exists($namespace) ? $namespace : '';
    }
}

/**
 * 获取插件类的类名
 *
 * @param string $name  插件名
 * @param string $class 当前类名
 *
 * @return mixed
 */
if ( ! function_exists('get_plugin_instance')) {
    function get_plugin_instance($name, $class = '')
    {
        $object = get_plugin_class($name, $class);

        return $object ? new $object : '';
    }
}
/**
 * 刷新插件配置
 * @return bool
 */
if ( ! function_exists('plugin_refresh_hooks')) {

    function plugin_refresh_hooks()
    {

    }
}

/**
 * 递归创建文件夹
 *
 * @param     $path
 * @param int $mode 文件夹权限
 *
 * @return bool
 */
if ( ! function_exists('mk_dirs')) {
    function mk_dirs($path, int $mode = 0777): bool
    {
        if ( ! is_dir(dirname($path))) {
            mk_dirs(dirname($path));
        }

        if ( ! file_exists($path)) {
            return mkdir($path, $mode);
        }

        return true;
    }
}

/**
 * 创建目录及文件
 *
 * @param $file
 *
 * @return void
 */
if ( ! function_exists('mkDirFile')) {
    function mkDirFile($file)
    {
        $path = pathinfo($file, PATHINFO_DIRNAME);
        if ( ! is_dir($path)) {
            mkdir($path, 0777, true);
        }
    }
}

/**
 * 数据写入文件
 *
 * @param $file
 * @param $content
 *
 * @return false|int
 */
if ( ! function_exists('write_file')) {
    function write_file($file, $content)
    {
        $dir = dirname($file);
        if ( ! is_dir($dir)) {
            mk_dirs($dir);
        }

        return @file_put_contents($file, $content);
    }
}

/**
 * 复制文件
 *
 * @param string $src
 * @param string $dst
 *
 * @return bool
 */
if ( ! function_exists('copy_file')) {
    function copy_file(string $src, string $dst): bool
    {
        $dir = dirname($dst);
        if ( ! is_dir($dir)) {
            mk_dirs($dir);
        }

        return @copy($src, $dst);
    }
}

if ( ! function_exists('recursive_dir_copy')) {
    /**
     * 文件夹文件（深）拷贝
     *
     * @param string $src 来源文件夹
     * @param string $dst 目的地文件夹
     *
     * @return bool
     */
    function recursive_dir_copy($src, $dst)
    {
        if (empty($src) || empty($dst)) {
            return false;
        }
        $dir = opendir($src);
        mk_dirs($dst);
        while (false !== ($file = readdir($dir))) {
            if (($file != '.') && ($file != '..')) {
                $srcRecursiveDir = $src.DIRECTORY_SEPARATOR.$file;
                $dstRecursiveDir = $dst.DIRECTORY_SEPARATOR.$file;
                if (is_dir($srcRecursiveDir)) {
                    recursive_dir_copy($srcRecursiveDir, $dstRecursiveDir);
                } else {
                    copy($srcRecursiveDir, $dstRecursiveDir);
                }
            }
        }
        closedir($dir);

        return true;
    }
}

/**
 * 传入时间戳,计算距离现在的时间
 *
 * @param number $time 时间戳
 *
 * @return string     返回多少以前
 */
function word_time($time)
{
    $time = (int)substr($time, 0, 10);
    $int  = time() - $time;
    $str  = '';
    if ($int <= 2) {
        $str = sprintf('刚刚', $int);
    } elseif ($int < 60) {
        $str = sprintf('%d秒前', $int);
    } elseif ($int < 3600) {
        $str = sprintf('%d分钟前', floor($int / 60));
    } elseif ($int < 86400) {
        $str = sprintf('%d小时前', floor($int / 3600));
    } elseif ($int < 1728000) {
        $str = sprintf('%d天前', floor($int / 86400));
    } else {
        $str = date('Y-m-d H:i:s', $time);
    }

    return $str;
}

/*
 * php截取指定两个字符之间字符串
 * */
function get_between_str($input, $start, $end)
{
    $substr = substr($input, strlen($start) + strpos($input, $start), (strlen($input) - strpos($input, $end)) * (-1));

    return $substr;
}
